<template>
    <div class="vue-flow-edit-menu" draggable="true" @dragstart="onDragstart" @dragend="onDragend">
        <slot name="content" :model="model">
            <span>{{model.label}}</span>
        </slot>
        <i class="el-icon-arrow-right" v-if="!hideArrow"></i>
    </div>
</template>

<script>
    import {VueFlowEditorProvider} from "@/editor/editor";
    import {formatNodeModel, formatPos} from "../utils/utils";

    export default {
        name: "vue-flow-edit-menu",
        inject: {
            [VueFlowEditorProvider]: {}
        },
        props: {
            model: {type: Object, require: true},              // 节点新建的时候的配置对象
            hideArrow: {type: Boolean},                         // 是否隐藏箭头
        },
        data() {
            return {
                handler: {
                    dragenter: (e) => {
                        e.dataTransfer.dropEffect = 'move'
                    },
                    dragover: (e) => {
                        e.preventDefault()
                    },
                    dragleave: (e) => {
                        e.dataTransfer.dropEffect = 'none'
                    },
                    drop: async e => {
                        let model = {...this.model}
                        formatNodeModel(model, this[VueFlowEditorProvider].props.activityConfig)

                        let {id, shape, size} = model

                        shape = shape || 'rect'

                        id = id || String(new Date().getTime())
                        if (typeof id === "function") {
                            id = await id()
                        }

                        const {clientX, clientY} = e
                        let {x, y} = this.graph.getPointByClient(clientX, clientY)

                        const {beforeAdd, afterAdd} = this[VueFlowEditorProvider].editorState.props

                        const formatData = formatPos({
                            x,
                            y,
                            size,
                            shape,
                        })

                        model = {
                            ...(model),
                            id,
                            shape: formatData.shape,
                            size: formatData.size,
                            x: formatData.x,
                            y: formatData.y,
                        }


                        try {
                            if (!!beforeAdd) {
                                await beforeAdd(model, 'node')
                            }
                            this.graph.emit('add-node:before', model)
                            this.graph.add('node', model)
                            this.graph.paint()
                            this.graph.emit('add-node:after', model)
                            if (!!afterAdd) {
                                await afterAdd(model, 'node')
                            }
                        } catch (e) {
                            console.error(e)
                        }
                    }
                },
            }
        },
        computed: {
            graph() {
                return this[VueFlowEditorProvider].editorState.graph
            },
            container() {
                return !!this.graph ? this.graph.get('container') : null
            },
        },
        methods: {
            onDragstart(e) {
                e.dataTransfer.effectAllowed = 'move'

                this.container.addEventListener('dragenter', this.handler.dragenter)
                this.container.addEventListener('dragover', this.handler.dragover)
                this.container.addEventListener('dragleave', this.handler.dragleave)
                this.container.addEventListener('drop', this.handler.drop)
            },
            onDragend() {
                this.container.removeEventListener('dragenter', this.handler.dragenter)
                this.container.removeEventListener('dragover', this.handler.dragover)
                this.container.removeEventListener('dragleave', this.handler.dragleave)
                this.container.removeEventListener('drop', this.handler.drop)
            },
        },
    }
</script>

<style lang="scss">
</style>